home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2003 August / MW 8 2003 CD1.iso / Inside Macworld / Product News / gimp-1.2.4.sit / gimp-1.2.4 / plug-ins / perl / examples / sethspin < prev    next >
Encoding:
Text File  |  2000-06-06  |  7.8 KB  |  216 lines

  1. #!/usr/app/bin/perl
  2.  
  3. eval 'exec /usr/app/bin/perl  -S $0 ${1+"$@"}'
  4.     if 0; # not running under some shell
  5.  
  6. #
  7. # Note: Seth has transferred the maintainer `position' to me, so bother me
  8. # instead of him now :-)
  9. #       - Steinar H. Gunderson <sgunderson@bigfoot.com>
  10.  
  11.  
  12. # This one's all mine.  Well, its GPL/Artisitic but I'm the author and creator. 
  13. # You need gimp 1.1 or better for this; too much has changed, and I don't think
  14. # 1.0.x had a perspective PDB function anyway 
  15.  
  16. # Here's the working theory on this:
  17. #  There's a function called spinlayer which will spin from a spinlayer to a
  18. #  destlayer.  It won't touch those 2 layers at all, and will leave its results
  19. #  on the top of the layer stack.
  20. #
  21. #  If the user wants to spin back, it will take 1/2 the layers otherwise required
  22. #  per call to the spin_layer, so that the number of total layers comes out the
  23. #  same.  
  24. #
  25. #  The main function makes a new image, copies the source and destination onto it
  26. #  with appropriate offsets, and passes this image with the bottom 2 layers to
  27. #  spin_layer.  At the end, remove the original 2 layers, since they won't be 
  28. #  needed, and add in some Layer comments for timing your gif.
  29. #
  30. ################################################################################
  31. #  Many thanks to Steinar and Marc, for expressing an intrest in the script that
  32. #  kept me going, and to Steinar in particular for helping me track down why the
  33. #  script was crashing gimp (hint - don't make layers of height=0, and if you do
  34. #  make sure you're logging to console since the Gtk messagebox will never show
  35. #  up due to a rapid segfault).
  36. #
  37. #  Just a comment on that: We fixed the bug, so height=0 no longer segfaults, but
  38. #  gives the error message it should. However, if GIMP segfaults, you should try
  39. #  logging to console to make sure you get all applicable error messages. This
  40. #  will make it _much_ easier to find the bug. - Steinar
  41. #
  42. # Revision History:
  43. # 1.0 - Initial (too early) release
  44. # 1.1 - Second (still ugly) release: Made the perspective setting actually do
  45. #       something
  46. # 1.2 - Used some of the convienence functions, and made things a little eaiser
  47. #       from the user's standpoint too.  Also moved it from the 
  48. #       Filters->Animations-> menu to Xtns->Animations.  I think its 
  49. #       clearer whats going on this way.  It also works w/ any 2 layers now.
  50. # 1.5 - Some debugging by Steinar and myself to make it work again.
  51. # 1.6 - Moved some renaming into the main loop, more cleanups.
  52. #
  53. # TODO: Clean it up; allow for other effects (skewing, ripples?) while spinning;        
  54.  
  55. # Seth Burgess
  56. # <sjburges@gimp.org>
  57.  
  58. use Gimp;  # No qw(:auto) - Trying to use all OO-styling
  59. use Gimp::Fu;
  60. use Gimp::Util;
  61.  
  62. # Gimp::set_trace(TRACE_ALL);
  63.  
  64. sub saw {  # a sawtooth function on PI
  65.     ($val) = @_;
  66.     if ($val < 3.14159/2.0) {
  67.         return ($val/3.14159);
  68.     } elsif ($val < 3.14159) {
  69.         return (-1+$val/3.14159); 
  70.     } elsif ($val < 3.14159+3.14159/2.0) {
  71.         return ($val/3.14159);
  72.     } else {
  73.         return (-1+$val/3.14159); 
  74.     }
  75.  
  76. sub spin_layer { # the function for actually spinning the layer
  77.     my ($img, $spin, $dest, $numframes, $prp) = @_;
  78.  
  79.     my $floater,  # The transformed image
  80.        $framelay, # The background color
  81.        $frameno;  # The current frame
  82.  
  83.     # Now let's spin it!
  84.     $stepsize = 3.14159/$numframes; # in radians 
  85.     $frameno = 0;
  86.     for ($i=0; $i<=3.14159; $i+=$stepsize) {
  87.         Gimp->progress_update ($i/3.14159);
  88.  
  89.         # create a new layer for spinning
  90.         $framelay = ($i < 3.14159/2.0) ? $spin->copy(1) : $dest->copy(1);
  91.         $img->add_layer($framelay, 0);
  92.         $floater = $framelay->copy(1);
  93.         $img->add_layer($floater, 0);
  94.  
  95.         # spin it a step
  96.         $img->selection_all();
  97.         @x = $img->selection_bounds();
  98.         $img->selection_none();
  99.  
  100.         # x[1],x[2]                  x[3],x[2]
  101.         # x[1],x[4]                  x[3],x[4]
  102.         my($y1, $y3);
  103.         $y1 = int($x[2]+$spin->height *sin($i)/2);
  104.         $y3 = int($x[4]-$spin->height *sin($i)/2);
  105.  
  106.     # height must be != 0
  107.         $y3++ if ($y1 == $y3);
  108.  
  109.         $floater = Gimp->perspective($floater, 1,
  110.                        $x[1]+saw($i)*$prp*$framelay->width,$y1,  
  111.                        $x[3]-saw($i)*$prp*$framelay->width,$y1,
  112.                        $x[1]-saw($i)*$prp*$framelay->width,$y3,  
  113.                        $x[3]+saw($i)*$prp*$framelay->width,$y3);
  114.         $framelay->fill(1); # BG-IMAGE-FILL
  115.  
  116.     # merge the two layers together before we continue
  117.         $img->set_visible($floater, $framelay);
  118.         $framelay = $img->merge_visible_layers(0);
  119.  
  120.     $frameno++;
  121.     $framelay->set_name("Spin Layer $frameno (50ms)");
  122.     }
  123. }
  124.  
  125. register "seth_spin",
  126.          "Seth Spin",
  127.          "Take one image.  Spin it about the horizontal axis, and end up with another image.  I made it for easy web buttons.",
  128.          "Seth Burgess",
  129.          "Seth Burgess <sjburges\@gimp.org>",
  130.          "1.6",
  131.          N_"<Toolbox>/Xtns/Animation/Seth Spin...",
  132.          "*",
  133.          [
  134.           [PF_DRAWABLE, "source", "What drawable to spin from?"],
  135.           [PF_DRAWABLE, "destination","What drawable to spin to?"],
  136.           [PF_INT8, "frames", "How many frames to use?", 16],
  137.           [PF_COLOR, "background", "What color to use for background if not transparent", [0,0,0]],
  138.           [PF_SLIDER, "perspective", "How much perspective effect to get", 40, [0,255,5]],
  139.           [PF_TOGGLE, "spin_back", "Also spin back?" , 1],
  140.           [PF_TOGGLE, "convert_indexed", "Convert to indexed?", 1],
  141.          ],
  142.          [],
  143.          ['gimp-1.1'],
  144.          sub {
  145.     my($src,$dest,$frames,$color,$perspective,$spinback,$indexed) = @_;
  146.     
  147.     $oldbackground = Gimp->palette_get_background();
  148.     Gimp->palette_set_background($color);
  149.  
  150.     $perspective = $perspective/255.0; # PF_SLIDER doesn't work right for < 1
  151.  
  152.     Gimp->progress_init(__"Seth Spin...",-1);
  153.  
  154.     # Copy souce and destination to new image
  155.     
  156.     $maxwide = ($src->width > $dest->width) ? $src->width : $dest->width;
  157.     $maxhigh = ($src->height > $dest->height) ? $src->height: $dest->height;
  158.  
  159.     $img = Gimp->image_new($maxwide, $maxhigh, RGB);
  160.     $tmpimglayer = $img->add_new_layer(0,3,1); # have to have a layer before displaying
  161.     $img->display_new;
  162.  
  163.     $src->edit_copy();
  164.     $spinlayer = $tmpimglayer->edit_paste(1);
  165.     $spinlayer->floating_sel_to_layer();
  166.  
  167.     $dest->edit_copy();
  168.     $destlayer = $tmpimglayer->edit_paste(1);
  169.     $destlayer->floating_sel_to_layer();
  170.  
  171.     $tmpimglayer->remove_layer;                # remove temporary layer.
  172.  
  173.     # set the layer size to be the full layer for each copied layer
  174.     $spinlayer->resize($maxwide, $maxhigh, $spinlayer->offsets);
  175.     $destlayer->resize($maxwide, $maxhigh, $destlayer->offsets);
  176.  
  177.     # need an even number of frames for spinback
  178.     if ($frames%2 && $spinback) {
  179.         $frames++;
  180.         Gimp->message(__"An even number of frames is needed for spin back.\nAdjusted frames up to $frames");
  181.     }
  182.  
  183.     spin_layer($img, $spinlayer, $destlayer, $spinback ? $frames/2 : $frames, $perspective);
  184.    
  185.     # go back from destination to spinlayer if spinning back 
  186.     if ($spinback) { 
  187.         @layerlist = $img->get_layers();
  188.         spin_layer($img, $destlayer, $spinlayer, $frames/2, $perspective);
  189.     }    
  190.  
  191.     # remove the original 2 pasted layers
  192.     $img->remove_layer($destlayer);
  193.     $img->remove_layer($spinlayer);
  194.  
  195.     # unhide and name layers (Give timings)
  196.     @all_layers = $img->get_layers;
  197.     $img->set_visible(@all_layers);
  198.  
  199.     if ($spinback) {
  200.         $all_layers[$frames/2-1]->set_name(__"Spin Layer DEST (250ms)");
  201.     }
  202.     $all_layers[$frames-1]->set_name(__"Spin Layer SRC (250ms)");  
  203.  
  204.     # indexed conversion wants a display for some reason
  205.     if ($indexed) { 
  206.         $img->convert_indexed(1,MAKE_PALETTE,255,0,1,"buffy" ); 
  207.     } 
  208.  
  209.     Gimp->palette_set_background($oldbackground);
  210.     return();
  211. };
  212.  
  213. exit main;
  214.  
  215.